unit ImageTools;

interface

uses Dialogs, SysUtils, DB, Graphics;

type TWindowSize = record
  Angle, XPos, YPos: Integer;
  OX, OY: Boolean;
  Text: String;
end;

type TImageTools = class
  private
  public
	  function CheckEmptyBitmap(ABitmap: TBitmap): Boolean;
    function DefBitmapSizeIfEmpty(ABitmap: TBitmap): TBitmap;
    procedure RotateImage90(ABitmap, BBitmap: TBitmap);
    procedure RotateImage180(ABitmap, BBitmap: TBitmap);
    procedure RotateImage270(ABitmap, BBitmap: TBitmap);
    procedure DrawRotateText(SourceBitmap, DestBitmap: TBitmap; WindowSize: array of TWindowSize);
    procedure SplitImageVer(SourceImage, DestImage: TBitmap);
    procedure SplitImageHor(SourceImage, DestImage: TBitmap);
    function GetBitmap(ADataSource: TDataSource; Field: String):TBitmap;
    function GetBitmapByID(ADataSource: TDataSource; IDFieldName, IDFieldNameRes, ResFieldName: String):TBitmap;
  end;

var
  HImageTools: TImageTools;

implementation

//---------------------------------------------------------------------------
function TImageTools.DefBitmapSizeIfEmpty(ABitmap: TBitmap): TBitmap;
begin
  if(CheckEmptyBitmap(ABitmap) = True)then
  begin
    ABitmap.Height := 1;
    ABitmap.Width := 1;
  end;
  Result := ABitmap;
end;

//---------------------------------------------------------------------------
function TImageTools.CheckEmptyBitmap(ABitmap: TBitmap): Boolean;
var hResult: Boolean;
begin
  hResult := False;
  if((ABitmap.Width = 0)or(ABitmap.Height = 0)) then hResult := True;
  if((ABitmap.Width >= 1)and(ABitmap.Height >= 0)) then hResult := False;
  Result := hResult;
end;

//---------------------------------------------------------------------------
procedure TImageTools.RotateImage90(ABitmap, BBitmap: TBitmap);
var
  x, y: Integer;
begin
  x := 0;
  y := 0;
  BBitmap.Width := ABitmap.Height;
  BBitmap.Height := ABitmap.Width;
  while(x <> ABitmap.Width) do
  begin
    while(y <> ABitmap.Height) do
    begin
      BBitmap.Canvas.Pixels[BBitmap.Width-y, x] := ABitmap.Canvas.Pixels[x, y];
      Inc(y);
    end;
    y := 0;
    Inc(x);
  end;
end;

//---------------------------------------------------------------------------
procedure TImageTools.RotateImage180(ABitmap, BBitmap: TBitmap);
var
  x, y: Integer;
begin
  x := 0;
  y := 0;
  BBitmap.Width := ABitmap.Width;
  BBitmap.Height := ABitmap.Height;
  while(x <> ABitmap.Width) do
  begin
    while(y <> ABitmap.Height) do
    begin
      BBitmap.Canvas.Pixels[BBitmap.Width-x, BBitmap.Height-y] := ABitmap.Canvas.Pixels[x, y];
      Inc(y);
    end;
    y := 0;
    Inc(x);
  end;
end;

//---------------------------------------------------------------------------
procedure TImageTools.RotateImage270(ABitmap, BBitmap: TBitmap);
var
  x, y: Integer;
begin
  x := 0;
  y := 0;
  BBitmap.Width := ABitmap.Height;
  BBitmap.Height := ABitmap.Width;
  while(x <> ABitmap.Width) do
  begin
    while(y <> ABitmap.Height) do
    begin
      BBitmap.Canvas.Pixels[y, BBitmap.Height-x] := ABitmap.Canvas.Pixels[x, y];
      Inc(y);
    end;
    y := 0;
    Inc(x);
  end;
end;

//---------------------------------------------------------------------------
procedure TImageTools.DrawRotateText(SourceBitmap, DestBitmap: TBitmap; WindowSize: array of TWindowSize);
var
  x, y, angle, CharLen, BorderStep, i: Integer;
  ox, oy: Boolean;
  text: String;
  abitmap, bbitmap: TBitmap;
begin
  if(Length(WindowSize) > 0) then
  begin
    CharLen := 6;
    BorderStep := 13;
    i := 0;
    if((DestBitmap.Width < 86)or(DestBitmap.Height < 86)) then
    begin
      DestBitmap.Width := SourceBitmap.Width+(BorderStep*2);
      DestBitmap.Height := SourceBitmap.Height+(BorderStep*2);
    end;
    DestBitmap.Canvas.Draw(BorderStep, BorderStep, SourceBitmap);
    while(i <= Length(WindowSize)-1) do
    begin
      abitmap := TBitmap.Create();
      bbitmap := TBitmap.Create();
      x := WindowSize[i].xpos;
      y := WindowSize[i].ypos;
      angle := WindowSize[i].angle;
      ox := WindowSize[i].ox;
      oy := WindowSize[i].oy;
      if (ox) then Dec(x, Round(bbitmap.Width/2));
      if (oy) then Dec(y, Round(bbitmap.Height/2));
      text := WindowSize[i].text;
      abitmap.Width := CharLen*Length(text);
      abitmap.Height := BorderStep-2;
      abitmap.Canvas.Brush.Style := bsClear;
      abitmap.Canvas.Font.Size := 8;
      abitmap.Canvas.TextOut(0, 0, text);
      case(angle)of
        90:  RotateImage90(abitmap, bbitmap);
        180: RotateImage180(abitmap, bbitmap);
        270: RotateImage270(abitmap, bbitmap);
        0:
        begin
          if(x+abitmap.Width > DestBitmap.Width) then DestBitmap.Width := x+abitmap.Width;
          bbitmap.Assign(abitmap);
        end;
      end;
      DestBitmap.Canvas.Draw(x, y, bbitmap);
      abitmap.Free();
      bbitmap.Free();
      Inc(i);
    end;
    if(Length(WindowSize) = 0) then DestBitmap.Assign(SourceBitmap);
  end else
  if(CheckEmptyBitmap(DestBitmap) = True)then
  begin
    DestBitmap.Assign(SourceBitmap);
  end;
end;

//---------------------------------------------------------------------------
procedure TImageTools.SplitImageVer(SourceImage, DestImage: TBitmap);
var
  CurrentHeight: Integer;
begin
  CurrentHeight := DestImage.Height;
  if(CheckEmptyBitmap(DestImage) = True) then
  begin
    DestImage.Assign(SourceImage);
  end
  else
  begin
    if(CheckEmptyBitmap(SourceImage) = False) then
    begin
      DestImage.Height := DestImage.Height + SourceImage.Height;
      if(DestImage.Width < SourceImage.Width) then
      begin
        DestImage.Width := SourceImage.Width;
      end;
      DestImage.Canvas.Draw(0, CurrentHeight, SourceImage);
    end;
  end;
end;

//---------------------------------------------------------------------------
procedure TImageTools.SplitImageHor(SourceImage, DestImage: TBitmap);
var
  CurrentWidth: Integer;
begin
  CurrentWidth := DestImage.Width;
  if(CheckEmptyBitmap(DestImage) = True) then
  begin
    DestImage.Assign(SourceImage);
  end
  else
  begin
    if(CheckEmptyBitmap(SourceImage) = False) then
    begin
      DestImage.Width := DestImage.Width + SourceImage.Width;
      DestImage.Canvas.Draw(CurrentWidth, 0, SourceImage);
    end;
  end;
end;

//---------------------------------------------------------------------------
function TImageTools.GetBitmap(ADataSource: TDataSource; Field: String):TBitmap;
var
  MyBitmap: TBitmap;
begin
  MyBitmap := TBitmap.Create();
  if(not ADataSource.DataSet.IsEmpty) then
  begin
    MyBitmap.Assign(ADataSource.DataSet.FieldByName(Field));
  end;
  Result := DefBitmapSizeIfEmpty(MyBitmap);
end;

//---------------------------------------------------------------------------
function TImageTools.GetBitmapByID(ADataSource: TDataSource; IDFieldName, IDFieldNameRes, ResFieldName: String):TBitmap;
var
  MyBitmap: TBitmap;
begin
  MyBitmap := TBitmap.Create();
  if((not ADataSource.DataSet.IsEmpty)and(IDFieldName <> '')and(IDFieldNameRes <> '')and(ResFieldName <> '')) then
  begin
    ADataSource.DataSet.Filtered := False;
    ADataSource.DataSet.Filter := Format('%s=%s', [IDFieldName, IDFieldNameRes]);
    //ShowMessage(ADataSource.DataSet.Filter);
    ADataSource.DataSet.Filtered := True;
    MyBitmap.Assign(ADataSource.DataSet.FieldByName(ResFieldName));
    ADataSource.DataSet.Filtered := False;
    ADataSource.DataSet.Filter := '';
  end;
  Result := DefBitmapSizeIfEmpty(MyBitmap);
end;

end.
